﻿using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using UnityExtensions;

namespace UnityEngine
{
	public static class TransformRectExt
	{
		public static Matrix4x4 GetTransformPointToMatrix4x4(this Transform self, [NotNull] Transform target)
		{
			if (target == null) throw new ArgumentNullException(nameof(target));
			var matrix = target.worldToLocalMatrix * self.localToWorldMatrix;
			return matrix;
		}

		public static Bounds TransformBoundsTo(this Transform self, Bounds bounds, [NotNull] Transform target)
		{
			var boundsNew = new Bounds();
			var matrix = self.GetTransformPointToMatrix4x4(target);//target.worldToLocalMatrix * self.localToWorldMatrix;
			boundsNew.min = matrix.MultiplyPoint(bounds.min);
			boundsNew.max = matrix.MultiplyPoint(bounds.max);
			return boundsNew;
		}
		/// <summary>
		/// Transforms position list from local space to world space.
		/// </summary>
		/// <param name="self"></param>
		/// <param name="point"></param>
		/// <param name="target"></param>
		public static Vector3 TransformPointTo(this Transform self,Vector3 point, [NotNull] Transform target)
		{
			if (target == null) throw new ArgumentNullException(nameof(target));
#if !true
			var vector3 = self.TransformPoint(point);
			vector3 = target.InverseTransformPoint(vector3);
#else
			var matrix = self.GetTransformPointToMatrix4x4(target);//target.worldToLocalMatrix * self.localToWorldMatrix;
			var vector3 = matrix.MultiplyPoint(point);
			//var vector3 = self.localToWorldMatrix.MultiplyPoint(point);
			//vector3 = target.worldToLocalMatrix.MultiplyPoint(vector3);
#endif
			return vector3;
		}
		public static void TransformPoint(this Transform self,IList<Vector3> pointList)
		{
			for (var i = 0; i < pointList.Count; i++)
			{
				var it = pointList[i];
				pointList[i] = self.TransformPoint(it);
				pointList[i] = self.localToWorldMatrix.MultiplyPoint(it);
			}
		}

		public static Vector3[] GetWorldCorners(this Transform self, Bounds bounds)
		{
			var corners = new Vector3[4];
			self.GetWorldCorners(bounds,corners);
			return corners;
		}
		public static void GetWorldCorners(this Transform self, Bounds bounds, Vector3[] corners)
		{
			var rect = new Rect {min = bounds.min, max = bounds.max};
			self.GetWorldCorners(rect,corners);

		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="self"></param>
		/// <param name="rect">local rect</param>
		/// <param name="corners">out put corner to the list</param>
		public static void GetWorldCorners(this Transform self, Rect rect,Vector3[] corners)
		{
			rect.GetCorners(corners);
			self.TransformPoint(corners);
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="self"></param>
		/// <param name="rect">local rect</param>
		/// <returns>corner list size 4,</returns>
		public static Vector3[] GetWorldCorners(this Transform self, Rect rect)
		{
			var corners = new Vector3[4];
			self.GetWorldCorners(rect,corners);
			return corners;
		}
	}
}